<template>
  <div class="vue-component-communication">
    <page-header title="Vue 组件通讯"></page-header>
    <el-row>
      <el-col :span="11">
        <!--父传子 props  -->
        <div class="title">一、父传子 props</div>
        <div class="content-box">
          父组件
          <div class="input-box">
            <el-input clearable v-model="parentValue"></el-input>
          </div>
          <Son :parentValue="parentValue" />
        </div>
      </el-col>
      <el-col :span="12">
        <!-- 子传父 $emit -->
        <div class="title">二、子传父 $emit</div>
        <div class="content-box">
          父组件
          <div class="input-box">子组件传回的内容：{{ mySonInfo }}</div>
          <Son inputShow btnShow @changeSonInfo="changeSonInfo" />
        </div>
      </el-col>
    </el-row>
    <el-row>
      <el-col :span="11">
        <!-- 祖传孙 provide inject -->
        <div class="title">三、祖传孙 provide inject</div>
        <div class="content-box">
          祖组件：{{ grandSonInfo }}
          <div class="input-box">
            <el-input clearable v-model="grandpaValue" />
          </div>
          <Parent />
        </div>
      </el-col>
      <el-col :span="12">
        <div class="title">四、父调子方法 $refs\ $children</div>
        <!-- $refs -->
        <div class="content-box">
          <div>$ref 父组件：{{ sonValue }}</div>
          <el-button style="margin: 12px 0" @click="getSonFun"
            >调用子组件方法</el-button
          >
          <Son inputShow ref="sonEle" />
        </div>
      </el-col>
    </el-row>
    <el-row>
      <el-col :span="11">
        <!-- vuex -->
        <div class="title">五、vuex</div>
        <div class="content-box">
          该项目使用pinia进行状态管理，vuex不在此处演示
        </div>
      </el-col>
      <el-col :span="12">
        <!--  pinia -->
        <div class="title">六、pinia</div>
        <div class="content-box">
          <div class="input-box">
            <el-input clearable v-model="piniaValue" />
            <el-button @click="piniaChange">改变pinia的值</el-button>
          </div>
          <ComponentOne />
          <ComponentTwo /></div
      ></el-col>
    </el-row>
    <el-row>
      <el-col :span="11">
        <!-- $bus -->
        <div class="title">七、事件总线 $bus(vue2 使用)</div>
        <div class="content-box">
          vue3不推荐使用，若需要使用可以借助第三方库
        </div>
      </el-col>
      <el-col :span="12">
        <div class="title">八、$attr、$listeners</div>
        <div class="content-box">
          父组件{{ attrNum }}
          <ComponentTwo
            title="子组件"
            :attrNum="attrNum"
            @attrChange="attrChange"
          />
        </div>
      </el-col>
    </el-row>
  </div>
</template>

<script lang="ts" setup>
import Son from "./component/son.vue";
import Parent from "./component/parent.vue";
import ComponentOne from "./component/componentOne.vue";
import ComponentTwo from "./component/componentTwo.vue";
import { useVueComponent } from "@/store/vueComponentCommunication";
import { ref, provide } from "vue";

// props
const parentValue = ref("我是父组件inpute的内容");

// $emit
const mySonInfo = ref("");
const changeSonInfo = (data: string) => {
  mySonInfo.value = data;
};

// provide inject
const grandpaValue = ref("我是祖组件inpute的内容");
const grandSonInfo = ref("接收孙组件的内容");
const renewalGrandpa = (str: string) => {
  grandSonInfo.value = str;
};
provide("grandpaValue", { grandpaValue, renewalGrandpa });

// pinia
const store = useVueComponent();
const piniaValue = ref("pinia管理的状态");
const piniaChange = () => {
  store.piniaValChange(piniaValue.value);
};

// $refs
const sonEle = ref<any>(null);
const sonValue = ref("");
const getSonFun = () => {
  if (sonEle.value?.sonFunByRef) {
    sonValue.value = sonEle.value?.sonFunByRef();
  }
};

// $attr
const attrNum = ref(0);
const attrChange = () => {
  attrNum.value++;
};
</script>
<style scoped lang="scss">
.vue-component-communication {
  .content-box {
    padding: 12px;
    margin-bottom: 12px;
    background-color: bisque;
    .input-box {
      display: flex;
      margin: 8px 0;
      .el-input {
        width: 200px;
        margin-right: 12px;
      }
    }
  }
  .title {
    font-weight: 600;
    padding-top: 16px;
    border-top: 1px solid #d5d5d5;
    margin: 0 0 20px 0;
  }
  & .el-col-11:nth-child(2n-1) {
    margin-right: 16px;
  }
}
</style>
